# 支付表
from tortoise import fields, models
from datetime import datetime, timedelta

from models.enums import OrderStatus, PaymentChannel, PaymentStatus # 从自定义文件中导入枚举类型
from utils.snowflake import snowflake  # 导入雪花算法类的实例
from models.user import User
from models.address import Address
from models.products import Product


# 模拟的订单表
class OrderFake(models.Model):
    """订单表模型（模拟的订单表）"""
    id = fields.BigIntField(pk=True, description="订单ID")
    order_number = fields.CharField(
        max_length=64,
        unique=True,
        default=lambda: f"ORDER{snowflake.generate_id()}",
        description="商户订单号（雪花算法生成）"
    )
    user = fields.ForeignKeyField(
        "models.User", 
        related_name="orders_user", 
        description="关联的用户"
    )
    address = fields.ForeignKeyField(
        "models.Address",
        related_name="orders_address",
        description="收货地址"
    )
    status = fields.CharEnumField(
        OrderStatus, 
        default=OrderStatus.PENDING, 
        description="订单状态"
    )
    total_amount = fields.DecimalField(
        max_digits=12, 
        decimal_places=2, 
        description="订单总金额（元）"
    )
    actual_amount = fields.DecimalField(
        max_digits=12, 
        decimal_places=2, 
        description="实际支付金额（元）"
    )
    payment_channel = fields.CharEnumField(
        PaymentChannel,
        null=True,
        description="选择的支付渠道"
    )
    
    # 时间戳
    created_at = fields.DatetimeField(auto_now_add=True, description="订单创建时间")
    updated_at = fields.DatetimeField(auto_now=True, description="订单更新时间")
    paid_at = fields.DatetimeField(null=True, description="支付成功时间")
    cancelled_at = fields.DatetimeField(null=True, description="订单取消时间")

    class Meta:
        table = "fakeorders"
    
    async def update_status(self, new_status: OrderStatus):
        """订单状态更新"""
        if new_status == OrderStatus.CANCELLED:
            # 同步关联支付记录
            self.status = OrderStatus.CANCELLED
            self.cancelled_at = datetime.now()
            await self.save(update_fields=["status", "cancelled_at", "updated_at"])
            # 用户主动取消订单，如果关联订单存在待支付的支付记录，支付状态变更为已取消
            if self.payments.filter(pay_status=PaymentStatus.PENDING).exists():
                payment = await self.payments.filter(pay_status=PaymentStatus.PENDING).first()
                payment.pay_status = PaymentStatus.CANCELLED
                await payment.save()
        elif new_status == OrderStatus.PAID:
            # 支付后订单状态改为已支付
            self.status = OrderStatus.PAID
            self.paid_at = datetime.now()
            await self.save(update_fields=["status", "paid_at", "updated_at"])
        else:
                self.status = new_status
                await self.save(update_fields=["status", "updated_at"])
        
        

class OrderItemFake(models.Model):
    """订单商品表模拟（关联订单与商品）"""
    id = fields.BigIntField(pk=True)
    order = fields.ForeignKeyField("models.OrderFake", related_name="items")
    product = fields.ForeignKeyField("models.Product", related_name="order_items")
    quantity = fields.IntField(description="购买数量")
    price = fields.DecimalField(max_digits=10, decimal_places=2)  # 购买时单价
            

# 订单不会 “自动” 取消，需要通过定时任务或异步队列主动检测并触发取消操作。（定时任务或者设置redis的过期键）        
# 支付表
class Payment(models.Model):
    """支付记录表模型（订单创建成功后才能生成）"""
    id = fields.BigIntField(pk=True, description="支付记录ID")
    
    # 关联订单
    order = fields.ForeignKeyField(
        "models.OrderFake",
        related_name="payments",
        on_delete=fields.CASCADE,
        description="关联的订单"
    )
    pay_amount = fields.DecimalField(
        max_digits=12, 
        decimal_places=2, 
        description="支付金额（元）"
    )
    pay_status = fields.CharEnumField(
        PaymentStatus, 
        default=PaymentStatus.PENDING, 
        description="支付状态"
    )
    pay_channel = fields.CharEnumField(
        PaymentChannel, 
        description="支付渠道"
    )
    pay_number = fields.CharField(
        max_length=64, 
        unique=True,
        default=lambda: f"PAY{snowflake.generate_id()}",
        description="支付编号（唯一，雪花算法生成）"
    )
    transaction_id = fields.CharField(
        max_length=64, 
        null=True, 
        description="第三方支付平台交易号"
    )

    
    # 时间戳字段
    created_at = fields.DatetimeField(auto_now_add=True, description="支付记录创建时间")
    updated_at = fields.DatetimeField(auto_now=True, description="支付记录更新时间")
    timeout_at = fields.DatetimeField(
        default=lambda: datetime.now() + timedelta(minutes=10),
        description="支付超时时间（10分钟）"
    )

    class Meta:
        table = "payment_records"
        indexes = [
            ("order_id",),
            ("pay_status", "created_at"),
        ]

    async def update_status(self, new_status: PaymentStatus):
        """支付状态更新"""
        self.pay_status = new_status
        await self.save(update_fields=["pay_status", "updated_at"])
        
        # 同步更新订单状态
        if new_status == PaymentStatus.PAID:
            # 支付成功，更新订单状态（分期支付也是订单已经支付了，后期还款都是还的第三方中介，和商家之间没有关系）
            order = await self.order
            order.status = OrderStatus.PAID
            order.paid_at = datetime.now()
            await order.save()
        elif new_status in [PaymentStatus.REFUNDED, PaymentStatus.TIMEOUT]:
            # 支付超时或退款，更新订单状态
            order = await self.order
            order.status = OrderStatus.CANCELLED
            await order.save()


